//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Resource Application Block
//===============================================================================

using System;
using System.Globalization;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using EntLibContrib.Resource;

namespace EntLibContrib.WinResourceQuickStart
{
	/// <summary>
	/// Main display form for the Message of the day application. This application demonstrates
	/// taking resources directly from Xml and Binary resource files.  No resources are embedded in the assembly.
	/// Also, because all resource managers implement the "ApplyResources" method, similar to that found in
	/// <see cref="System.ComponentModel.ComponentResourceManager"/>, this sample demonstrates applying resources to all form components
	/// using reflection.
	/// </summary>
	/// <remarks>
	/// 	<para>The advantage of taking resources direct from Xml files is that they can be edited
	/// and updated without the need to recompile the application</para>
	/// 	<para>The "ApplyResources" method in all resource managers allows you to simulate the
	/// Windows form designer "Localizable" property getting your resources from any configurable
	/// resource source including a Database. Note that you must not set the "Localizable" property
	/// to True otherwise the windows forms designer will do its own resource management.</para>
	/// </remarks>
	public partial class MessageOfTheDayForm : Form
	{
		#region Fields
		// Todays date used to set the default message of the day
		private DateTime today = System.DateTime.Today;
		// Array of supported Cultures containing English, French and German
		private CultureInfo[] cultures = new CultureInfo[3] { new CultureInfo("en-GB"), new CultureInfo("fr-FR"), new CultureInfo("de-DE") };
		// Resource Manager holding the message resources. This is the default resource manager
		// in configuration, hence no need to give the instance name.  This is also a Binary resource
		// which means that the resources come directly from the "*.resources" files.
		private ResourceManager messageResources = ResourceFactory.GetResourceManager();
		// Resource Manager holding the form resources.  Because this is not the default resource manager
		// you need to include the instance name. This is also an Xml resource which means that the 
		// resources come directly from the "*.resx" file which can be edited independantly from the
		// application.
		private ResourceManager formResources = ResourceFactory.GetResourceManager("Form Resource Manager");
		#endregion

		#region Constructors
		/// <summary>
		/// Initializes a new instance of the <see cref="MessageOfTheDayForm"/> class
		/// using the default invariant culture. The invariant (neutral) culture has 
		/// been set to English
		/// </summary>
		public MessageOfTheDayForm ()
			: this(CultureInfo.InvariantCulture)
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="MessageOfTheDayForm"/> class
		/// with a given <see cref="CultureInfo"/>.
		/// </summary>
		/// <param name="culture">The culture.</param>
		public MessageOfTheDayForm (CultureInfo culture)
		{
			// auto-generated method to initialise all form components
			InitializeComponent();
			// initialise the culture and apply resources
			InitializeCulture(culture);
		}
		#endregion

		#region Event Handlers
		/// <summary>
		/// Handles the SelectedIndexChanged event of the comboCulture control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void comboCulture_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			// get the culture box
			ComboBox cultureBox = (ComboBox)sender;
			// change the current culture to the selected culture
			InitializeCulture((CultureInfo)cultureBox.SelectedItem);
		}

		/// <summary>
		/// Handles the SelectedIndexChanged event of the comboDays control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void comboDays_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			// change the message of the day text and its label to the selected day
			MessageOfTheDay();
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Set the message of the day.
		/// </summary>
		/// <remarks>
		/// The message of the day label is fetched from form resources using a strongly typed class,
		/// while the message of the day text is fetched from message resources using an indexer.
		/// </remarks>
		public void MessageOfTheDay()
		{
			// Message of the day label. Note the use of the generated strongly typed class
			// this class was generated from the Enterprise Library configuration tool
			string messageLabel = FormResources.labelMessageOfTheDay_Text;
			this.labelMessageOfTheDay.Text = messageLabel + ( (DayName)this.comboDays.SelectedItem ).NameValue;

			// Message of the day text. Here we use string manipulation to calculate the resource key
			// and then apply the key to the resource manager default indexer for string resources.
			string message = messageResources[( (DayName)this.comboDays.SelectedItem ).NameKey + "Message"];
			this.textMessage.Text = message;
		}
		#endregion

		#region Private Methods
		/// <summary>
		/// Reinitialize the form components that take localised information.
		/// </summary>
		/// <remarks>Note how we demonstrate the use of the ApplyResources method from the resource manager.
		/// This method uses reflection to match resources found in the resource file with the properties of
		/// a given form component.  For clarity I have used the exact same component key names as would
		/// be generated by the Windows Form designer.  Have a look at the FormResources.resx file to see 
		/// how these key names are formatted. Note how each property, except for the default property, takes
		/// an initial double chevron.</remarks>
		private void ApplyResources()
		{
			this.SuspendLayout();
			formResources.ApplyResources(this, "$this");
			formResources.ApplyResources(this.comboCulture, "comboCulture");
			formResources.ApplyResources(this.comboDays, "comboDays");
			formResources.ApplyResources(this.labelMessageOfTheDay, "labelMessageOfTheDay");
			formResources.ApplyResources(this.pictureFlag, "pictureFlag");
			formResources.ApplyResources(this.textMessage, "textMessage");
			this.ResumeLayout(false);
		}

		/// <summary>
		/// Initializes the current thread culture.
		/// </summary>
		/// <param name="culture">The culture.</param>
		private void InitializeCurrentCulture (CultureInfo culture)
		{
			// set culture for formatting
			Thread.CurrentThread.CurrentCulture = culture;
			// set culture for resources
			Thread.CurrentThread.CurrentUICulture = culture;
		}

		/// <summary>
		/// Initializes the supported cultures combo box.
		/// </summary>
		private void InitializeCultures()
		{
			this.comboCulture.DataSource = cultures;
			this.comboCulture.DisplayMember = "NativeName";
			InitializeDays();
		}

		/// <summary>
		/// Initializes the culture.
		/// </summary>
		/// <param name="culture">The culture.</param>
		private void InitializeCulture(CultureInfo culture)
		{
			InitializeCurrentCulture(culture);
			ApplyResources();
			InitializeCultures();
		}

		/// <summary>
		/// Initializes the days of the week combo.
		/// </summary>
		private void InitializeDays ()
		{
			// create a bindable generic list of day names
			List<DayName> dayNames = new List<DayName>(7);
			DayName dayName;
			DayName todayName = null;

			// populate the list of day names
			foreach (string dayOfTheWeek in System.Enum.GetNames(typeof(DayOfWeek)))
			{
				// get the day name for the current culture
				dayName = new DayName(dayOfTheWeek, messageResources[dayOfTheWeek]);
				dayNames.Add(dayName);
				if ( dayOfTheWeek == today.DayOfWeek.ToString() )
					todayName = dayName;
			}

			// bind the list of day names to the combo box
			this.comboDays.DataSource = dayNames;
			this.comboDays.DisplayMember = "NameValue";
			// set the selected day to today.
			this.comboDays.SelectedItem = todayName;
		}
		#endregion
	}
}